<template>
	<Drawer ref="drawerWrapper" :value="value" @input="handleInput" :width="width" :class-name="outerClasses" v-bind="$attrs" v-on="$listeners">
		<!-- 所有插槽内容显示在这里 ↓ -->

		<template v-for="(slots, slotsName) in $slots">
			<template v-if="slotsName !== 'default'">
				<render-dom v-for="(render, index) in slots" :key="`b_drawer_${slotsName}_${index}`" :render="() => render" :slot="slotsName"> </render-dom>
			</template>
			<template v-else>
				<div :class="`${prefix}-body-wrapper`" :key="`b_drawer_${slotsName}`">
					<render-dom v-for="(render, index) in slots" :key="`b_drawer_${slotsName}_${index}`" :render="() => render" :slot="slotsName"> </render-dom>
				</div>
			</template>
		</template>
		<!-- 所有插槽内容显示在这里 ↑ -->
		<div v-if="draggable" :style="triggerStyle" :class="`${prefix}-trigger-wrapper`" @mousedown="handleTriggerMousedown">
			<slot name="trigger">
				<drag-drawer-trigger></drag-drawer-trigger>
			</slot>
		</div>
		<div v-if="$slots.footer" :class="`${prefix}-footer`">
			<slot name="footer"></slot>
		</div>
	</Drawer>
</template>

<script>
import RenderDom from '@/libs/render-dom';
import DragDrawerTrigger from './drag-drawer-trigger.vue';
import Mixin from './mixin';
import { on, off } from '@/libs/tools';
import './index.less';
export default {
	name: 'BDrawer',
	components: {
		RenderDom,
		DragDrawerTrigger
	},
	mixins: [Mixin],
	props: {
		value: {
			type: Boolean,
			default: false
		},
		width: {
			type: [String, Number],
			default: 256
		},
		// 是否可拖动修改宽度
		draggable: {
			type: Boolean,
			default: false
		},
		// 最小拖动宽度
		minWidth: {
			type: [String, Number],
			default: 256
		}
	},
	data() {
		return {
			canMove: false,
			wrapperWidth: 0,
			wrapperLeft: 0
		};
	},
	computed: {
		outerClasses() {
			const classesArray = [`${this.prefix}-wrapper`, this.canMove ? 'no-select pointer-events-none' : ''];
			return classesArray.join(' ');
		},
		placement() {
			return this.$attrs.placement;
		},
		innerWidth() {
			const width = this.width;
			return width <= 100 ? (this.wrapperWidth * width) / 100 : width;
		},
		triggerStyle() {
			return {
				[this.placement]: `${this.innerWidth}px`,
				position: this.$attrs.inner ? 'absolute' : 'fixed'
			};
		}
	},
	methods: {
		handleInput(status) {
			this.$emit('input', status);
		},
		handleTriggerMousedown(event) {
			this.canMove = true;
			this.$emit('on-resize-start');
			// 防止鼠标选中抽屉中文字，造成拖动trigger触发浏览器原生拖动行为
			window.getSelection().removeAllRanges();
		},
		handleMousemove(event) {
			if (!this.canMove) return;
			// 更新容器宽度和距离左侧页面距离，如果是window则距左侧距离为0
			this.setWrapperWidth();
			const left = event.pageX - this.wrapperLeft;
			// 如果抽屉方向为右边，宽度计算需用容器宽度减去left
			let width = this.placement === 'right' ? this.wrapperWidth - left : left;
			// 限定做小宽度
			width = Math.max(width, parseFloat(this.minWidth));
			event.atMin = width === parseFloat(this.minWidth);
			// 如果当前width不大于100，视为百分比
			if (width <= 100) width = (width / this.wrapperWidth) * 100;
			this.$emit('update:width', parseInt(width));
			this.$emit('on-resize', event);
		},
		handleMouseup(event) {
			this.canMove = false;
			this.$emit('on-resize-end');
		},
		setWrapperWidth() {
			const { width, left } = this.$refs.drawerWrapper.$el.getBoundingClientRect();
			this.wrapperWidth = width;
			this.wrapperLeft = left;
		}
	},
	mounted() {
		on(document, 'mousemove', this.handleMousemove);
		on(document, 'mouseup', this.handleMouseup);
		this.setWrapperWidth();
	},
	beforeDestroy() {
		off(document, 'mousemove', this.handleMousemove);
		off(document, 'mouseup', this.handleMouseup);
	}
};
</script>
